#include <QVector2D>
#include <QDebug>
#include "ball.h"

// TODO convert velocity to vector
Ball::Ball(QObject *parent) : QObject(parent)
{
    velocity = 60;
    resistAcc = 30;
    offsetSum = 0;
    radius = 20;
    frame.setSize(QSize(radius, radius) * 2);

    accAnimasList = new QVector<Vector2DAnima*>;
    componentsAccList = new QVector<QVector2D*>;

    pushBallAnima = createNewAccAnima();
    pushBallAnima->setDuration(200);
    pushBallAnima->setStartValue(QVector2D(0, 0));
    pushBallAnima->setEndValue(QVector2D(0, 0));

}

Ball::~Ball()
{
    for (auto anima : *accAnimasList)
    {
        disconnect(anima);
        delete anima;
    }
    for (auto v2d : *componentsAccList)
        delete v2d;
    delete componentsAccList;
    delete accAnimasList;
}

void Ball::pushLeft()
{
    if (pushBallAnima->state() != QAbstractAnimation::Running || pushBallAnima->keyValueAt(0.2).x() > 0)
    {
        pushBallAnima->stop();
        pushBallAnima->setKeyValueAt(0.2, QVector2D(-200, 0));
        pushBallAnima->start();
    }
}

void Ball::pushRight()
{
    if (pushBallAnima->state() != QAbstractAnimation::Running || pushBallAnima->keyValueAt(0.2).x() < 0)
    {
        pushBallAnima->stop();
        pushBallAnima->setKeyValueAt(0.2, QVector2D(200, 0));
        pushBallAnima->start();
    }
}

Vector2DAnima* Ball::createNewAccAnima() // 如果通过工厂方法创建动画，删除动画时会自动从列表中移除动画
{
    QVector2D *v2d = new QVector2D;
    Vector2DAnima *anima = new Vector2DAnima(v2d);
    connect(anima, &Vector2DAnima::deleted, this, [=]{
        this->componentsAccList->removeOne(v2d);
        this->accAnimasList->removeOne(anima);
        delete v2d;
    }, Qt::DirectConnection);
    accAnimasList->push_back(anima);
    componentsAccList->push_back(v2d);
    return anima;
}

QVector2D *Ball::addNewAcc(const QVector2D &v2d)
{
    auto newAcc = new QVector2D(v2d);
    componentsAccList->append(newAcc);
    return newAcc;
}

bool Ball::removeAcc(QVector2D *v2d)
{
    if (componentsAccList->contains(v2d))
    {
        componentsAccList->removeOne(v2d);
        return true;
    }
    return false;
}

bool Ball::removeAccAnima(Vector2DAnima *anima)
{
    if (accAnimasList->contains(anima))
    {
        accAnimasList->removeOne(anima);
        return true;
    }
    return false;
}

QVector2D Ball::sumOfComponentsAcc()
{
    QVector2D v2d;
    for (auto i : *componentsAccList)
    {
        v2d += *i;
    }
    return v2d;
}


Vector2DAnima::Vector2DAnima(QVector2D *v2d, QObject *parent) : QVariantAnimation(parent)
{
    m_v2d = v2d;
}

Vector2DAnima::~Vector2DAnima()
{
    emit deleted();
}

QVector2D Vector2DAnima::keyValueAt(qreal step) const
{
    return QVariantAnimation::keyValueAt(step).value<QVector2D>();
}

void Vector2DAnima::updateCurrentValue(const QVariant &value)
{
    *m_v2d = value.value<QVector2D>();
}


